using AutoMapper;
using B.S.NewMedical.Api.Write.Application.Command.Doctor;
using B.S.NewMedical.Domain.Appointment;
using B.S.NewMedical.Domain.Hospital;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace B.S.NewMedical.Api.Write.Application.Handler.Doctor
{
    /// <summary>
    /// 获取医生待就诊患者列表处理器
    /// </summary>
    public class GetWaitingPatientsHandler : IRequestHandler<GetWaitingPatientsCommand, ApiResult<List<WaitingPatientDto>>>
    {
        private readonly IBaseRepository<Registration> _registrationRepository;
        private readonly IBaseRepository<PatientModel> _patientRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<GetWaitingPatientsHandler> _logger;

        public GetWaitingPatientsHandler(
            IBaseRepository<Registration> registrationRepository,
            IBaseRepository<PatientModel> patientRepository,
            IMapper mapper,
            ILogger<GetWaitingPatientsHandler> logger)
        {
            _registrationRepository = registrationRepository;
            _patientRepository = patientRepository;
            _mapper = mapper;
            _logger = logger;
        }

        public async Task<ApiResult<List<WaitingPatientDto>>> Handle(GetWaitingPatientsCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取医生{DoctorId}的待就诊患者列表", request.DoctorId);

                // 参数验证
                if (request.DoctorId <= 0)
                    return new ApiResult<List<WaitingPatientDto>> { Code = ApiEnum.Fail, Msg = "医生ID不能为空" };

                // 默认查询当天
                var visitDate = request.VisitDate?.Date ?? DateTime.Today;

                // 查询待就诊的挂号记录
                var registrations = await _registrationRepository.GetAll()
                    .Where(r => r.Doctor_id == request.DoctorId 
                             && r.Status == "待就诊" 
                             && r.Visit_date.Date == visitDate
                             && !r.IsDeleted)
                    .OrderBy(r => r.Slot_no)
                    .ToListAsync(cancellationToken);

                // 获取患者信息
                var patientIds = registrations.Select(r => r.Patient_id).ToList();
                var patients = await _patientRepository.GetAll()
                    .Where(p => patientIds.Contains(p.Id) && !p.IsDeleted)
                    .ToListAsync(cancellationToken);

                // 组装结果
                var result = registrations.Select(r =>
                {
                    var patient = patients.FirstOrDefault(p => p.Id == r.Patient_id);
                    return new WaitingPatientDto
                    {
                        RegistrationId = r.Id,
                        CardNo = r.Card_no,
                        PatientId = r.Patient_id,
                        PatientName = patient?.Name ?? "未知患者",
                        SlotNo = r.Slot_no,
                        CreateTime = r.Create_time,
                        Fee = r.Fee
                    };
                }).ToList();

                _logger.LogInformation("成功获取到{Count}条待就诊记录", result.Count);

                return new ApiResult<List<WaitingPatientDto>>
                {
                    Code = ApiEnum.Success,
                    Msg = "获取成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取待就诊患者列表时发生错误，医生ID: {DoctorId}", request.DoctorId);
                return new ApiResult<List<WaitingPatientDto>>
                {
                    Code = ApiEnum.Fail,
                    Msg = "获取待就诊患者列表失败"
                };
            }
        }
    }
} 